home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / dropde-2.zip / ITEMS.QC < prev    next >
Text File  |  1996-09-18  |  30KB  |  1,377 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;    
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {    
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.     
  155.     if (other.classname != "player")
  156.         return;
  157.     
  158.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  159.     {
  160.         if (other.health >= 250)
  161.             return;
  162.         if (!T_Heal(other, self.healamount, 1))
  163.             return;
  164.     }
  165.     else
  166.     {
  167.         if (!T_Heal(other, self.healamount, 0))
  168.             return;
  169.     }
  170.     
  171.     sprint(other, "You receive ");
  172.     s = ftos(self.healamount);
  173.     sprint(other, s);
  174.     sprint(other, " health\n");
  175.     
  176. // health touch sound
  177.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  178.  
  179.     stuffcmd (other, "bf\n");
  180.     
  181.     self.model = string_null;
  182.     self.solid = SOLID_NOT;
  183.  
  184.     // Megahealth = rot down the player's super health
  185.     if (self.healtype == 2)
  186.     {
  187.         other.items = other.items | IT_SUPERHEALTH;
  188.         self.nextthink = time + 5;
  189.         self.think = item_megahealth_rot;
  190.         self.owner = other;
  191.     }
  192.     else
  193.     {
  194.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  195.         {
  196.             if (deathmatch)
  197.                 self.nextthink = time + 20;
  198.             self.think = SUB_regen;
  199.         }
  200.     }
  201.     
  202.     activator = other;
  203.     SUB_UseTargets();                // fire all targets / killtargets
  204. };    
  205.  
  206. void() item_megahealth_rot =
  207. {
  208.     other = self.owner;
  209.     
  210.     if (other.health > other.max_health)
  211.     {
  212.         other.health = other.health - 1;
  213.         self.nextthink = time + 1;
  214.         return;
  215.     }
  216.  
  217. // it is possible for a player to die and respawn between rots, so don't
  218. // just blindly subtract the flag off
  219.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  220.     
  221.     if (deathmatch && deathmatch != 2)  // deathmatch 2 is silly old rules
  222.     {
  223.         self.nextthink = time + 20;
  224.         self.think = SUB_regen;
  225.     }
  226. };
  227.  
  228. /*
  229. ===============================================================================
  230.  
  231. ARMOR
  232.  
  233. ===============================================================================
  234. */
  235.  
  236. void() armor_touch;
  237.  
  238. void() armor_touch =
  239. {
  240.     local    float    type, value, bit;
  241.     
  242.     if (other.health <= 0)
  243.         return;
  244.     if (other.classname != "player")
  245.         return;
  246.  
  247.     if (self.classname == "item_armor1")
  248.     {
  249.         type = 0.3;
  250.         value = 100;
  251.         bit = IT_ARMOR1;
  252.     }
  253.     if (self.classname == "item_armor2")
  254.     {
  255.         type = 0.6;
  256.         value = 150;
  257.         bit = IT_ARMOR2;
  258.     }
  259.     if (self.classname == "item_armorInv")
  260.     {
  261.         type = 0.8;
  262.         value = 200;
  263.         bit = IT_ARMOR3;
  264.     }
  265.     if (other.armortype*other.armorvalue >= type*value)
  266.         return;
  267.         
  268.     other.armortype = type;
  269.     other.armorvalue = value;
  270.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  271.  
  272.     self.solid = SOLID_NOT;
  273.     self.model = string_null;
  274.     if (deathmatch && deathmatch != 2)
  275.         self.nextthink = time + 20;
  276.     self.think = SUB_regen;
  277.  
  278.     sprint(other, "You got armor\n");
  279. // armor touch sound
  280.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  281.     stuffcmd (other, "bf\n");
  282.     
  283.     activator = other;
  284.     SUB_UseTargets();                // fire all targets / killtargets
  285. };
  286.  
  287.  
  288. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  289. */
  290.  
  291. void() item_armor1 =
  292. {
  293.     self.touch = armor_touch;
  294.     precache_model ("progs/armor.mdl");
  295.     setmodel (self, "progs/armor.mdl");
  296.     self.skin = 0;
  297.     setsize (self, '-16 -16 0', '16 16 56');
  298.     StartItem ();
  299. };
  300.  
  301. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  302. */
  303.  
  304. void() item_armor2 =
  305. {
  306.     self.touch = armor_touch;
  307.     precache_model ("progs/armor.mdl");
  308.     setmodel (self, "progs/armor.mdl");
  309.     self.skin = 1;
  310.     setsize (self, '-16 -16 0', '16 16 56');
  311.     StartItem ();
  312. };
  313.  
  314. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  315. */
  316.  
  317. void() item_armorInv =
  318. {
  319.     self.touch = armor_touch;
  320.     precache_model ("progs/armor.mdl");
  321.     setmodel (self, "progs/armor.mdl");
  322.     self.skin = 2;
  323.     setsize (self, '-16 -16 0', '16 16 56');
  324.     StartItem ();
  325. };
  326.  
  327. /*
  328. ===============================================================================
  329.  
  330. WEAPONS
  331.  
  332. ===============================================================================
  333. */
  334.  
  335. void() bound_other_ammo =
  336. {
  337.     if (other.ammo_shells > 100)
  338.         other.ammo_shells = 100;
  339.     if (other.ammo_nails > 200)
  340.         other.ammo_nails = 200;
  341.     if (other.ammo_rockets > 100)
  342.         other.ammo_rockets = 100;        
  343.     if (other.ammo_cells > 100)
  344.         other.ammo_cells = 100;        
  345. };
  346.  
  347.  
  348. float(float w) RankForWeapon =
  349. {
  350.     if (w == IT_LIGHTNING)
  351.         return 1;
  352.     if (w == IT_ROCKET_LAUNCHER)
  353.         return 2;
  354.     if (w == IT_SUPER_NAILGUN)
  355.         return 3;
  356.     if (w == IT_GRENADE_LAUNCHER || w == IT_FLAMETHROWER)
  357.         return 4;
  358.     if (w == IT_SUPER_SHOTGUN)
  359.         return 5;
  360.     if (w == IT_NAILGUN)
  361.         return 6;
  362.     return 7;
  363. };
  364.  
  365.  
  366. /*
  367. =============
  368. ChooseWeapon
  369. =============
  370. */
  371. void(float new) ChooseWeapon =
  372. {
  373.     local float or, nr;
  374.  
  375. // change self.weapon if desired
  376.     or = RankForWeapon (self.weapon);
  377.     nr = RankForWeapon (new);
  378.     if (nr < or)
  379.         self.weapon = new;
  380. };
  381.  
  382. /*
  383. =============
  384. weapon_touch
  385. =============
  386. */
  387.  
  388. void() weapon_touch =
  389. {
  390.     local    float    new;
  391.     local entity stemp;
  392.     local    float    leave;
  393.  
  394.     if (!(other.flags & FL_CLIENT))
  395.         return;
  396.  
  397.     if (deathmatch >= 2 || coop)
  398.         leave = 1;
  399.     else
  400.         leave = 0;
  401.     
  402.     if (self.classname == "weapon_nailgun")
  403.     {
  404.         if (leave && (other.items & IT_NAILGUN) && other.ammo_nails == 200)
  405.             return;
  406.         new = IT_NAILGUN;
  407.         other.ammo_nails = other.ammo_nails + 30;
  408.     }
  409.     else if (self.classname == "weapon_supernailgun")
  410.     {
  411.         if (leave && (other.items & IT_SUPER_NAILGUN) && other.ammo_nails == 200)
  412.             return;
  413.         new = IT_SUPER_NAILGUN;
  414.         other.ammo_nails = other.ammo_nails + 30;
  415.     }
  416.     else if (self.classname == "weapon_supershotgun")
  417.     {
  418.         if (leave && (other.items & IT_SUPER_SHOTGUN) && other.ammo_shells == 100)
  419.             return;
  420.         new = IT_SUPER_SHOTGUN;
  421.         other.ammo_shells = other.ammo_shells + 5;
  422.     }
  423.     else if (self.classname == "weapon_rocketlauncher")
  424.     {
  425.         if (leave && (other.items & IT_ROCKET_LAUNCHER)
  426.                 && other.ammo_rockets == 100)
  427.             return;
  428.         new = IT_ROCKET_LAUNCHER;
  429.         other.ammo_rockets = other.ammo_rockets + 5;
  430.     }
  431.     else if (self.classname == "weapon_grenadelauncher")
  432.     {
  433.         if (leave && (other.items & IT_GRENADE_LAUNCHER)
  434.                 && other.ammo_rockets == 100)
  435.             return;
  436.     // FLAMETHROWER
  437.     other.items = other.items | IT_FLAMETHROWER;
  438.     new = IT_GRENADE_LAUNCHER;
  439.         other.ammo_rockets = other.ammo_rockets + 5;
  440.     }
  441.     else if (self.classname == "weapon_lightning")
  442.     {
  443.         if (leave && (other.items & IT_LIGHTNING) && other.ammo_cells == 100)
  444.             return;
  445.         new = IT_LIGHTNING;
  446.         other.ammo_cells = other.ammo_cells + 15;
  447.     }
  448.     else
  449.         objerror ("weapon_touch: unknown classname");
  450.  
  451.     sprint (other, "You got the ");
  452.     sprint (other, self.netname);
  453.     sprint (other, "\n");
  454. // weapon touch sound
  455.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  456.     stuffcmd (other, "bf\n");
  457.  
  458.     bound_other_ammo ();
  459.  
  460. // change to the weapon
  461.     other.items = other.items | new;
  462.  
  463.     // Don't automatically change weapons if using morningstar and
  464.     // and fire button pressed.
  465.     if ( other.hook == world || (!other.button0) )
  466.     {
  467.         stemp = self;
  468.         self = other;
  469.  
  470.         ChooseWeapon(new);
  471.         W_SetCurrentAmmo();
  472.  
  473.         self = stemp;
  474.     }
  475.  
  476. // remove it in single player, or setup for respawning in deathmatch
  477.     self.model = string_null;
  478.     self.solid = SOLID_NOT;
  479.     if (deathmatch && deathmatch != 2)
  480.         self.nextthink = time + 30;
  481.     self.think = SUB_regen;
  482.     
  483.     activator = other;
  484.     SUB_UseTargets();                // fire all targets / killtargets
  485. };
  486.  
  487.  
  488. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  489. */
  490.  
  491. void() weapon_supershotgun =
  492. {
  493.     precache_model ("progs/g_shot.mdl");
  494.     setmodel (self, "progs/g_shot.mdl");
  495.     self.weapon = IT_SUPER_SHOTGUN;
  496.     self.netname = "Double-barrelled Shotgun";
  497.     self.touch = weapon_touch;
  498.     setsize (self, '-16 -16 0', '16 16 56');
  499.     StartItem ();
  500. };
  501.  
  502. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  503. */
  504.  
  505. void() weapon_nailgun =
  506. {
  507.     precache_model ("progs/g_nail.mdl");
  508.     setmodel (self, "progs/g_nail.mdl");
  509.     self.weapon = IT_NAILGUN;
  510.     self.netname = "nailgun";
  511.     self.touch = weapon_touch;
  512.     setsize (self, '-16 -16 0', '16 16 56');
  513.     StartItem ();
  514. };
  515.  
  516. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  517. */
  518.  
  519. void() weapon_supernailgun =
  520. {
  521.     precache_model ("progs/g_nail2.mdl");
  522.     setmodel (self, "progs/g_nail2.mdl");
  523.     self.weapon = IT_SUPER_NAILGUN;
  524.     self.netname = "Super Nailgun";
  525.     self.touch = weapon_touch;
  526.     setsize (self, '-16 -16 0', '16 16 56');
  527.     StartItem ();
  528. };
  529.  
  530. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  531. */
  532.  
  533. void() weapon_grenadelauncher =
  534. {
  535.     precache_model ("progs/g_rock.mdl");
  536.     setmodel (self, "progs/g_rock.mdl");
  537.     self.weapon = 3;
  538.     self.netname = "Grenade Launcher";
  539.     self.touch = weapon_touch;
  540.     setsize (self, '-16 -16 0', '16 16 56');
  541.     StartItem ();
  542. };
  543.  
  544. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  545. */
  546.  
  547. void() weapon_rocketlauncher =
  548. {
  549.     precache_model ("progs/g_rock2.mdl");
  550.     setmodel (self, "progs/g_rock2.mdl");
  551.     self.weapon = 3;
  552.     self.netname = "Rocket Launcher";
  553.     self.touch = weapon_touch;
  554.     setsize (self, '-16 -16 0', '16 16 56');
  555.     StartItem ();
  556. };
  557.  
  558.  
  559. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  560. */
  561.  
  562. void() weapon_lightning =
  563. {
  564.     precache_model ("progs/g_light.mdl");
  565.     setmodel (self, "progs/g_light.mdl");
  566.     self.weapon = 3;
  567.     self.netname = "Thunderbolt";
  568.     self.touch = weapon_touch;
  569.     setsize (self, '-16 -16 0', '16 16 56');
  570.     StartItem ();
  571. };
  572.  
  573.  
  574. /*
  575. ===============================================================================
  576.  
  577. AMMO
  578.  
  579. ===============================================================================
  580. */
  581.  
  582. float() W_BestWeapon;
  583.  
  584. void() ammo_touch =
  585. {
  586. local entity    stemp;
  587. local float        best;
  588.  
  589.     if (other.classname != "player")
  590.         return;
  591.     if (other.health <= 0)
  592.         return;
  593.  
  594. // if the player was using his best weapon, change up to the new one if better
  595.     stemp = self;
  596.     self = other;
  597.     best = W_BestWeapon();
  598.     self = stemp;
  599.  
  600. // shotgun
  601.     if (self.weapon == 1)
  602.     {
  603.         if (other.ammo_shells >= 100)
  604.             return;
  605.         other.ammo_shells = other.ammo_shells + self.aflag;
  606.     }
  607.  
  608. // spikes
  609.     if (self.weapon == 2)
  610.     {
  611.         if (other.ammo_nails >= 200)
  612.             return;
  613.         other.ammo_nails = other.ammo_nails + self.aflag;
  614.     }
  615.  
  616. //    rockets
  617.     if (self.weapon == 3)
  618.     {
  619.         if (other.ammo_rockets >= 100)
  620.             return;
  621.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  622.     }
  623.  
  624. //    cells
  625.     if (self.weapon == 4)
  626.     {
  627.         if (other.ammo_cells >= 200)
  628.             return;
  629.         other.ammo_cells = other.ammo_cells + self.aflag;
  630.     }
  631.  
  632.     bound_other_ammo ();
  633.     
  634.     sprint (other, "You got the ");
  635.     sprint (other, self.netname);
  636.     sprint (other, "\n");
  637. // ammo touch sound
  638.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  639.     stuffcmd (other, "bf\n");
  640.  
  641. // change to a better weapon if appropriate
  642.  
  643.     if (other.weapon == best)
  644.     {
  645.         stemp = self;
  646.         self = other;
  647.         self.weapon = W_BestWeapon();
  648.         W_SetCurrentAmmo ();
  649.         self = stemp;
  650.     }
  651.  
  652. // if changed current ammo, update it
  653.     stemp = self;
  654.     self = other;
  655.     W_SetCurrentAmmo();
  656.     self = stemp;
  657.  
  658. // remove it in single player, or setup for respawning in deathmatch
  659.     self.model = string_null;
  660.     self.solid = SOLID_NOT;
  661.     if (deathmatch && deathmatch != 2)
  662.         self.nextthink = time + 30;
  663.     
  664.     self.think = SUB_regen;
  665.  
  666.     activator = other;
  667.     SUB_UseTargets();                // fire all targets / killtargets
  668. };
  669.  
  670.  
  671.  
  672.  
  673. float WEAPON_BIG2 = 1;
  674.  
  675. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  676. */
  677.  
  678. void() item_shells =
  679. {
  680.     self.touch = ammo_touch;
  681.  
  682.     if (self.spawnflags & WEAPON_BIG2)
  683.     {
  684.         precache_model ("maps/b_shell1.bsp");
  685.         setmodel (self, "maps/b_shell1.bsp");
  686.         self.aflag = 40;
  687.     }
  688.     else
  689.     {
  690.         precache_model ("maps/b_shell0.bsp");
  691.         setmodel (self, "maps/b_shell0.bsp");
  692.         self.aflag = 20;
  693.     }
  694.     self.weapon = 1;
  695.     self.netname = "shells";
  696.     setsize (self, '0 0 0', '32 32 56');
  697.     StartItem ();
  698. };
  699.  
  700. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  701. */
  702.  
  703. void() item_spikes =
  704. {
  705.     self.touch = ammo_touch;
  706.  
  707.     if (self.spawnflags & WEAPON_BIG2)
  708.     {
  709.         precache_model ("maps/b_nail1.bsp");
  710.         setmodel (self, "maps/b_nail1.bsp");
  711.         self.aflag = 50;
  712.     }
  713.     else
  714.     {
  715.         precache_model ("maps/b_nail0.bsp");
  716.         setmodel (self, "maps/b_nail0.bsp");
  717.         self.aflag = 25;
  718.     }
  719.     self.weapon = 2;
  720.     self.netname = "nails";
  721.     setsize (self, '0 0 0', '32 32 56');
  722.     StartItem ();
  723. };
  724.  
  725. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  726. */
  727.  
  728. void() item_rockets =
  729. {
  730.     self.touch = ammo_touch;
  731.  
  732.     if (self.spawnflags & WEAPON_BIG2)
  733.     {
  734.         precache_model ("maps/b_rock1.bsp");
  735.         setmodel (self, "maps/b_rock1.bsp");
  736.         self.aflag = 10;
  737.     }
  738.     else
  739.     {
  740.         precache_model ("maps/b_rock0.bsp");
  741.         setmodel (self, "maps/b_rock0.bsp");
  742.         self.aflag = 5;
  743.     }
  744.     self.weapon = 3;
  745.     self.netname = "rockets";
  746.     setsize (self, '0 0 0', '32 32 56');
  747.     StartItem ();
  748. };
  749.  
  750.  
  751. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  752. */
  753.  
  754. void() item_cells =
  755. {
  756.     self.touch = ammo_touch;
  757.  
  758.     if (self.spawnflags & WEAPON_BIG2)
  759.     {
  760.         precache_model ("maps/b_batt1.bsp");
  761.         setmodel (self, "maps/b_batt1.bsp");
  762.         self.aflag = 12;
  763.     }
  764.     else
  765.     {
  766.         precache_model ("maps/b_batt0.bsp");
  767.         setmodel (self, "maps/b_batt0.bsp");
  768.         self.aflag = 6;
  769.     }
  770.     self.weapon = 4;
  771.     self.netname = "cells";
  772.     setsize (self, '0 0 0', '32 32 56');
  773.     StartItem ();
  774. };
  775.  
  776.  
  777. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  778. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  779. */
  780.  
  781. float WEAPON_SHOTGUN = 1;
  782. float WEAPON_ROCKET = 2;
  783. float WEAPON_SPIKES = 4;
  784. float WEAPON_BIG = 8;
  785. void() item_weapon =
  786. {
  787.     self.touch = ammo_touch;
  788.  
  789.     if (self.spawnflags & WEAPON_SHOTGUN)
  790.     {
  791.         if (self.spawnflags & WEAPON_BIG)
  792.         {
  793.             precache_model ("maps/b_shell1.bsp");
  794.             setmodel (self, "maps/b_shell1.bsp");
  795.             self.aflag = 40;
  796.         }
  797.         else
  798.         {
  799.             precache_model ("maps/b_shell0.bsp");
  800.             setmodel (self, "maps/b_shell0.bsp");
  801.             self.aflag = 20;
  802.         }
  803.         self.weapon = 1;
  804.         self.netname = "shells";
  805.     }
  806.  
  807.     if (self.spawnflags & WEAPON_SPIKES)
  808.     {
  809.         if (self.spawnflags & WEAPON_BIG)
  810.         {
  811.             precache_model ("maps/b_nail1.bsp");
  812.             setmodel (self, "maps/b_nail1.bsp");
  813.             self.aflag = 40;
  814.         }
  815.         else
  816.         {
  817.             precache_model ("maps/b_nail0.bsp");
  818.             setmodel (self, "maps/b_nail0.bsp");
  819.             self.aflag = 20;
  820.         }
  821.         self.weapon = 2;
  822.         self.netname = "spikes";
  823.     }
  824.  
  825.     if (self.spawnflags & WEAPON_ROCKET)
  826.     {
  827.         if (self.spawnflags & WEAPON_BIG)
  828.         {
  829.             precache_model ("maps/b_rock1.bsp");
  830.             setmodel (self, "maps/b_rock1.bsp");
  831.             self.aflag = 10;
  832.         }
  833.         else
  834.         {
  835.             precache_model ("maps/b_rock0.bsp");
  836.             setmodel (self, "maps/b_rock0.bsp");
  837.             self.aflag = 5;
  838.         }
  839.         self.weapon = 3;
  840.         self.netname = "rockets";
  841.     }
  842.     
  843.     setsize (self, '0 0 0', '32 32 56');
  844.     StartItem ();
  845. };
  846.  
  847.  
  848. /*
  849. ===============================================================================
  850.  
  851. KEYS
  852.  
  853. ===============================================================================
  854. */
  855.  
  856. void() key_touch =
  857. {
  858. local entity    stemp;
  859.  
  860.     if (other.classname != "player")
  861.         return;
  862.     if (other.health <= 0)
  863.         return;
  864.     if (other.items & self.items)
  865.         return;
  866.  
  867.     sprint (other, "You got the ");
  868.     sprint (other, self.netname);
  869.     sprint (other,"\n");
  870.  
  871.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  872.     stuffcmd (other, "bf\n");
  873.     other.items = other.items | self.items;
  874.  
  875.     if (!coop)
  876.     {    
  877.         self.solid = SOLID_NOT;
  878.         self.model = string_null;
  879.     }
  880.  
  881.     activator = other;
  882.     SUB_UseTargets();                // fire all targets / killtargets
  883. };
  884.  
  885.  
  886. void() key_setsounds =
  887. {
  888.     if (world.worldtype == 0)
  889.     {
  890.         precache_sound ("misc/medkey.wav");
  891.         self.noise = "misc/medkey.wav";
  892.     }
  893.     if (world.worldtype == 1)
  894.     {
  895.         precache_sound ("misc/runekey.wav");
  896.         self.noise = "misc/runekey.wav";
  897.     }
  898.     if (world.worldtype == 2)
  899.     {
  900.         precache_sound2 ("misc/basekey.wav");
  901.         self.noise = "misc/basekey.wav";
  902.     }
  903. };
  904.  
  905. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  906. SILVER key
  907. In order for keys to work
  908. you MUST set your maps
  909. worldtype to one of the
  910. following:
  911. 0: medieval
  912. 1: metal
  913. 2: base
  914. */
  915.  
  916. void() item_key1 =
  917. {
  918.     if (world.worldtype == 0)
  919.     {
  920.         precache_model ("progs/w_s_key.mdl");
  921.         setmodel (self, "progs/w_s_key.mdl");
  922.         self.netname = "silver key";
  923.     }
  924.     else if (world.worldtype == 1)
  925.     {
  926.         precache_model ("progs/m_s_key.mdl");
  927.         setmodel (self, "progs/m_s_key.mdl");
  928.         self.netname = "silver runekey";
  929.     }
  930.     else if (world.worldtype == 2)
  931.     {
  932.         precache_model2 ("progs/b_s_key.mdl");
  933.         setmodel (self, "progs/b_s_key.mdl");
  934.         self.netname = "silver keycard";
  935.     }
  936.     key_setsounds();
  937.     self.touch = key_touch;
  938.     self.items = IT_KEY1;
  939.     setsize (self, '-16 -16 -24', '16 16 32');
  940.     StartItem ();
  941. };
  942.  
  943. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  944. GOLD key
  945. In order for keys to work
  946. you MUST set your maps
  947. worldtype to one of the
  948. following:
  949. 0: medieval
  950. 1: metal
  951. 2: base
  952. */
  953.  
  954. void() item_key2 =
  955. {
  956.     if (world.worldtype == 0)
  957.     {
  958.         precache_model ("progs/w_g_key.mdl");
  959.         setmodel (self, "progs/w_g_key.mdl");
  960.         self.netname = "gold key";
  961.     }
  962.     if (world.worldtype == 1)
  963.     {
  964.         precache_model ("progs/m_g_key.mdl");
  965.         setmodel (self, "progs/m_g_key.mdl");
  966.         self.netname = "gold runekey";
  967.     }
  968.     if (world.worldtype == 2)
  969.     {
  970.         precache_model2 ("progs/b_g_key.mdl");
  971.         setmodel (self, "progs/b_g_key.mdl");
  972.         self.netname = "gold keycard";
  973.     }
  974.     key_setsounds();
  975.     self.touch = key_touch;
  976.     self.items = IT_KEY2;
  977.     setsize (self, '-16 -16 -24', '16 16 32');
  978.     StartItem ();
  979. };
  980.  
  981.  
  982.  
  983. /*
  984. ===============================================================================
  985.  
  986. END OF LEVEL RUNES
  987.  
  988. ===============================================================================
  989. */
  990.  
  991. void() sigil_touch =
  992. {
  993. local entity    stemp;
  994.  
  995.     if (other.classname != "player")
  996.         return;
  997.     if (other.health <= 0)
  998.         return;
  999.  
  1000.     centerprint (other, "You got the rune!");
  1001.  
  1002.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1003.     stuffcmd (other, "bf\n");
  1004.     self.solid = SOLID_NOT;
  1005.     self.model = string_null;
  1006.     serverflags = serverflags | (self.spawnflags & 15);
  1007.     self.classname = "";        // so rune doors won't find it
  1008.     
  1009.     activator = other;
  1010.     SUB_UseTargets();                // fire all targets / killtargets
  1011. };
  1012.  
  1013.  
  1014. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1015. End of level sigil, pick up to end episode and return to jrstart.
  1016. */
  1017.  
  1018. void() item_sigil =
  1019. {
  1020.     if (!self.spawnflags)
  1021.         objerror ("no spawnflags");
  1022.  
  1023.     precache_sound ("misc/runekey.wav");
  1024.     self.noise = "misc/runekey.wav";
  1025.  
  1026.     if (self.spawnflags & 1)
  1027.     {
  1028.         precache_model ("progs/end1.mdl");
  1029.         setmodel (self, "progs/end1.mdl");
  1030.     }
  1031.     if (self.spawnflags & 2)
  1032.     {
  1033.         precache_model2 ("progs/end2.mdl");
  1034.         setmodel (self, "progs/end2.mdl");
  1035.     }
  1036.     if (self.spawnflags & 4)
  1037.     {
  1038.         precache_model2 ("progs/end3.mdl");
  1039.         setmodel (self, "progs/end3.mdl");
  1040.     }
  1041.     if (self.spawnflags & 8)
  1042.     {
  1043.         precache_model2 ("progs/end4.mdl");
  1044.         setmodel (self, "progs/end4.mdl");
  1045.     }
  1046.     
  1047.     self.touch = sigil_touch;
  1048.     setsize (self, '-16 -16 -24', '16 16 32');
  1049.     StartItem ();
  1050. };
  1051.  
  1052. /*
  1053. ===============================================================================
  1054.  
  1055. POWERUPS
  1056.  
  1057. ===============================================================================
  1058. */
  1059.  
  1060. void() powerup_touch;
  1061.  
  1062.  
  1063. void() powerup_touch =
  1064. {
  1065. local entity    stemp;
  1066.  
  1067.     if (other.classname != "player")
  1068.         return;
  1069.     if (other.health <= 0)
  1070.         return;
  1071.  
  1072.     sprint (other, "You got the ");
  1073.     sprint (other, self.netname);
  1074.     sprint (other,"\n");
  1075.  
  1076.     if (deathmatch)
  1077.     {
  1078.         self.mdl = self.model;
  1079.         
  1080.         if ((self.classname == "item_artifact_invulnerability") ||
  1081.             (self.classname == "item_artifact_invisibility"))
  1082.             self.nextthink = time + 60*5;
  1083.         else
  1084.             self.nextthink = time + 60;
  1085.         
  1086.         self.think = SUB_regen;
  1087.     }    
  1088.  
  1089.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1090.     stuffcmd (other, "bf\n");
  1091.     self.solid = SOLID_NOT;
  1092.     other.items = other.items | self.items;
  1093.     self.model = string_null;
  1094.  
  1095. // do the apropriate action
  1096.     if (self.classname == "item_artifact_envirosuit")
  1097.     {
  1098.         other.rad_time = 1;
  1099.         other.radsuit_finished = time + 30;
  1100.     }
  1101.     
  1102.     if (self.classname == "item_artifact_invulnerability")
  1103.     {
  1104.         other.invincible_time = 1;
  1105.         other.invincible_finished = time + 30;
  1106.     }
  1107.     
  1108.     if (self.classname == "item_artifact_invisibility")
  1109.     {
  1110.         other.invisible_time = 1;
  1111.         other.invisible_finished = time + 30;
  1112.     }
  1113.  
  1114.     if (self.classname == "item_artifact_super_damage")
  1115.     {
  1116.         other.super_time = 1;
  1117.         other.super_damage_finished = time + 30;
  1118.     }    
  1119.  
  1120.     activator = other;
  1121.     SUB_UseTargets();                // fire all targets / killtargets
  1122. };
  1123.  
  1124.  
  1125.  
  1126. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1127. Player is invulnerable for 30 seconds
  1128. */
  1129. void() item_artifact_invulnerability =
  1130. {
  1131.     self.touch = powerup_touch;
  1132.  
  1133.     precache_model ("progs/invulner.mdl");
  1134.     precache_sound ("items/protect.wav");
  1135.     precache_sound ("items/protect2.wav");
  1136.     precache_sound ("items/protect3.wav");
  1137.     self.noise = "items/protect.wav";
  1138.     setmodel (self, "progs/invulner.mdl");
  1139.     self.netname = "Pentagram of Protection";
  1140.     self.items = IT_INVULNERABILITY;
  1141.     setsize (self, '-16 -16 -24', '16 16 32');
  1142.     StartItem ();
  1143. };
  1144.  
  1145. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1146. Player takes no damage from water or slime for 30 seconds
  1147. */
  1148. void() item_artifact_envirosuit =
  1149. {
  1150.     self.touch = powerup_touch;
  1151.  
  1152.     precache_model ("progs/suit.mdl");
  1153.     precache_sound ("items/suit.wav");
  1154.     precache_sound ("items/suit2.wav");
  1155.     self.noise = "items/suit.wav";
  1156.     setmodel (self, "progs/suit.mdl");
  1157.     self.netname = "Biosuit";
  1158.     self.items = IT_SUIT;
  1159.     setsize (self, '-16 -16 -24', '16 16 32');
  1160.     StartItem ();
  1161. };
  1162.  
  1163.  
  1164. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1165. Player is invisible for 30 seconds
  1166. */
  1167. void() item_artifact_invisibility =
  1168. {
  1169.     self.touch = powerup_touch;
  1170.  
  1171.     precache_model ("progs/invisibl.mdl");
  1172.     precache_sound ("items/inv1.wav");
  1173.     precache_sound ("items/inv2.wav");
  1174.     precache_sound ("items/inv3.wav");
  1175.     self.noise = "items/inv1.wav";
  1176.     setmodel (self, "progs/invisibl.mdl");
  1177.     self.netname = "Ring of Shadows";
  1178.     self.items = IT_INVISIBILITY;
  1179.     setsize (self, '-16 -16 -24', '16 16 32');
  1180.     StartItem ();
  1181. };
  1182.  
  1183.  
  1184. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1185. The next attack from the player will do 4x damage
  1186. */
  1187. void() item_artifact_super_damage =
  1188. {
  1189.     self.touch = powerup_touch;
  1190.  
  1191.     precache_model ("progs/quaddama.mdl");
  1192.     precache_sound ("items/damage.wav");
  1193.     precache_sound ("items/damage2.wav");
  1194.     precache_sound ("items/damage3.wav");
  1195.     self.noise = "items/damage.wav";
  1196.     setmodel (self, "progs/quaddama.mdl");
  1197.     self.netname = "Quad Damage";
  1198.     self.items = IT_QUAD;
  1199.     setsize (self, '-16 -16 -24', '16 16 32');
  1200.     StartItem ();
  1201. };
  1202.  
  1203.  
  1204.  
  1205. /*
  1206. ===============================================================================
  1207.  
  1208. PLAYER BACKPACKS
  1209.  
  1210. ===============================================================================
  1211. */
  1212.  
  1213. void() BackpackTouch =
  1214. {
  1215.     local string s;
  1216.     local entity stemp;
  1217.     local float best;
  1218.  
  1219.     if (other.classname != "player")
  1220.     {
  1221.         // DD fix to prevent backpack from falling through floor.
  1222.         if (self.movetype && other == world)
  1223.         {
  1224.             traceline (self.origin + '10 10 16', self.origin + '-10 -10 -32', TRUE
  1225.                     , other);
  1226.             self.origin_z = trace_endpos_z;
  1227.             traceline (self.origin + '-10 -10 16', self.origin + '10 10 -32', TRUE
  1228.                     , other);
  1229.             if (trace_endpos_z > self.origin_z)
  1230.                 self.origin_z = trace_endpos_z;
  1231.             setorigin(self, self.origin);
  1232.             self.velocity = '0 0 0';
  1233.             self.movetype = MOVETYPE_NONE;
  1234.         }
  1235.         return;
  1236.     }
  1237.     if (other.health <= 0)
  1238.         return;
  1239.         
  1240. // if the player was using his best weapon, change up to the new one if better
  1241.     stemp = self;
  1242.     self = other;
  1243.     best = W_BestWeapon();
  1244.     self = stemp;
  1245.  
  1246. // change weapons
  1247.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1248.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1249.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1250.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1251.  
  1252.     other.items = other.items | self.items;
  1253.     
  1254.     bound_other_ammo ();
  1255.  
  1256.     sprint (other, "You get ");
  1257.  
  1258.     if (self.ammo_shells)
  1259.     {
  1260.         s = ftos(self.ammo_shells);
  1261.         sprint (other, s);
  1262.         sprint (other, " shells  ");
  1263.     }
  1264.     if (self.ammo_nails)
  1265.     {
  1266.         s = ftos(self.ammo_nails);
  1267.         sprint (other, s);
  1268.         sprint (other, " nails ");
  1269.     }
  1270.     if (self.ammo_rockets >= 1)
  1271.     {
  1272.         s = ftos(floor(self.ammo_rockets));
  1273.         sprint (other, s);
  1274.         sprint (other, " rockets  ");
  1275.     }
  1276.     if (self.ammo_cells)
  1277.     {
  1278.         s = ftos(self.ammo_cells);
  1279.         sprint (other, s);
  1280.         sprint (other, " cells  ");
  1281.     }
  1282.     
  1283.     sprint (other, "\n");
  1284. // backpack touch sound
  1285.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1286.     stuffcmd (other, "bf\n");
  1287.  
  1288. // change to a better weapon if appropriate
  1289.     if ( other.weapon == best )
  1290.     {
  1291.         stemp = self;
  1292.         self = other;
  1293.         self.weapon = W_BestWeapon();
  1294.         self = stemp;
  1295.     }
  1296.  
  1297.     remove(self);
  1298.     
  1299.     self = other;
  1300.     W_SetCurrentAmmo ();
  1301. };
  1302.  
  1303.  
  1304. /*
  1305. void() BecomeExplosion;
  1306.  
  1307. void() BackpackDestroyed =
  1308. {
  1309.     if (!self.ammo_rockets)  // If no rockets / grenades, then no explosion.
  1310.     {
  1311.         remove(self);
  1312.         return;
  1313.     }
  1314.  
  1315.     local float dam;
  1316.     dam = 50 + (self.ammo_rockets * 2) + (random() * self.ammo_rockets);
  1317.     T_RadiusDamage (self, self.owner, dam, self);
  1318.  
  1319.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1320.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  1321.     WriteCoord (MSG_BROADCAST, self.origin_x);
  1322.     WriteCoord (MSG_BROADCAST, self.origin_y);
  1323.     WriteCoord (MSG_BROADCAST, self.origin_z);
  1324.  
  1325.     BecomeExplosion ();
  1326. };
  1327. */
  1328.  
  1329. /*
  1330. ===============
  1331. DropBackpack
  1332. ===============
  1333. */
  1334. void() DropBackpack =
  1335. {
  1336.     local entity    item;
  1337.     local float rockets;
  1338.  
  1339.     if (self.classname == "player")
  1340.         rockets = self.ammo_rockets - 0.8;
  1341.     else
  1342.         rockets = self.ammo_rockets;
  1343.     if (!(self.ammo_shells + self.ammo_nails + rockets + self.ammo_cells))
  1344.         return;    // nothing in it
  1345.  
  1346.     self.deadflag = DEAD_DYING;  // DD code
  1347.     item = spawn();
  1348.     item.origin = self.origin - '0 0 24';
  1349.  
  1350.     // DD code
  1351.   if (self.weapon == IT_FLAMETHROWER || self.weapon == IT_GRENADE_LAUNCHER)
  1352.      item.items = IT_FLAMETHROWER | IT_GRENADE_LAUNCHER;
  1353.     else
  1354.         item.items = self.weapon;
  1355.  
  1356.     item.ammo_shells = self.ammo_shells;
  1357.     item.ammo_nails = self.ammo_nails;
  1358.     item.ammo_rockets = rockets;
  1359.     item.ammo_cells = self.ammo_cells;
  1360.  
  1361.     item.velocity_z = 300;
  1362.     item.velocity_x = -100 + (random() * 200);
  1363.     item.velocity_y = -100 + (random() * 200);
  1364.     
  1365.     item.flags = FL_ITEM;
  1366.     item.solid = SOLID_TRIGGER;
  1367.     item.movetype = MOVETYPE_TOSS;
  1368.     setmodel (item, "progs/backpack.mdl");
  1369.     setsize (item, '-10 -10 0', '10 10 24');
  1370.     item.touch = BackpackTouch;
  1371.     
  1372.     item.nextthink = time + 120;    // remove after 2 minutes
  1373.     item.think = SUB_Remove;
  1374.  
  1375.     item.takedamage = DAMAGE_NO;
  1376. };
  1377.